package com.hw.sjms.visitorpattern;
/**
 * @Copyright 源码阅读网 http://coderead.cn
 */

import org.junit.Test;
import org.objectweb.asm.*;
import org.objectweb.asm.util.TraceClassVisitor;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;

/**
 * @author 鲁班大叔
 * @date 2021
 */
public class AsmTest {

    @Test
    public void testVisitClasses() throws IOException {
        byte[] bytes = Files.readAllBytes(new File("/Users/chehongwei/study/project/netty-learing/target/classes/com/hw/nio/buffer/Buffer.class").toPath());
        ClassReader reader = new ClassReader(bytes);
        reader.accept(new ClassVisitor(Opcodes.ASM5) {
            @Override
            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
                System.out.println(name);

                return new MethodVisitor(Opcodes.ASM5) {
                    int line;
                    @Override
                    public void visitLineNumber(int line, Label start) {
                        this.line = line;
                    }

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                        System.out.println("执行的方法：" + line + ":" + owner + "." + name);
                    }
                };
            }
        }, ClassReader.EXPAND_FRAMES);
    }

    @Test
    public void testWriter() throws IOException {
        byte[] bytes = Files.readAllBytes(new File("/Users/tommy/git/coderead-design-pattern/target/test-classes/coderead/design/pattern/Hello.class").toPath());
        ClassReader reader = new ClassReader(bytes);
        ClassWriter writer=new ClassWriter(ClassWriter.COMPUTE_MAXS);
        reader.accept(writer,ClassReader.EXPAND_FRAMES);

        MethodVisitor methodVisitor = writer.visitMethod(1, "sayHello2", "(Ljava/lang/String;)V",
                null, null);
        methodVisitor.visitInsn(Opcodes.AALOAD);
        // set writer add

      /*  //  方法的拷贝
        reader.accept(new ClassVisitor(Opcodes.ASM5) {
            @Override
            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
                if (name.equals("sayHello")){
                    writer.visitMethod(access, "sayHello2", desc, signature, exceptions);
                }
                return null;
            }
        }, ClassReader.EXPAND_FRAMES);*/

        byte[] newBytes = writer.toByteArray();
        Files.write(new File( System.getProperty("user.dir")+"/target/hello2.class")
                .toPath(),newBytes);
    }

    @Test
    public void testRead() throws IOException {
        byte[] bytes = Files.readAllBytes(new File("/Users/tommy/git/coderead-design-pattern/target/test-classes/coderead/design/pattern/Hello.class").toPath());
        ClassReader reader = new ClassReader(bytes);
        // 打印所有指令码
        reader.accept(new TraceClassVisitor(new PrintWriter(System.out)),ClassReader.EXPAND_FRAMES);
    }

    public static void main(String[] args) {
        System.out.println((byte)0x80);
    }
}
